package com.oritsh.dicom.utils;

import static com.oritsh.dicom.utils.DataSetHelper.putValueToDataSet;

import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.IOException;

import javax.sound.sampled.*;

import org.dcm4che.data.Attributes;
import org.dcm4che.data.Tag;
import org.dcm4che.data.UID;
import org.dcm4che.data.VR;
import org.dcm4che.io.DicomEncodingOptions;
import org.dcm4che.io.DicomInputStream;
import org.dcm4che.io.DicomOutputStream;

import com.oritsh.dicom.service.InstanceUIDService;
import com.oritsh.dicom.service.InstanceUIDSrvPixelmedImpl;

public class AudioHelper {
	
	public static final int DopplerAudio = 0001;
	public static final int VoiceAudio = 0002;
	public static final int PhonoAudio = 0003;
	
	static private byte[] convert2Byte(AudioInputStream audioStream) {
        // get the number of bytes to read
		AudioFormat format = audioStream.getFormat();
        int length = (int)(audioStream.getFrameLength() * format.getFrameSize());
        // read the entire stream
        byte[] samples = new byte[length];
        DataInputStream is = new DataInputStream(audioStream);
        try {
            is.readFully(samples);
        }
        catch (IOException ex) {
            ex.printStackTrace();
        }
        // return the samples
        return samples;
    }
	
    static public DicomInputStream audio2dcm(AudioInputStream sound,Attributes dataset) throws IOException {
    	AudioFormat format = sound.getFormat();	
    	
        putValueToDataSet(dataset, Tag.SpecificCharacterSet, "ISO_IR 192");
        putValueToDataSet(dataset, Tag.AudioType, VoiceAudio);
        putValueToDataSet(dataset, Tag.AudioSampleFormat, 0);
        putValueToDataSet(dataset, Tag.NumberOfChannels, 0);
        putValueToDataSet(dataset, Tag.NumberOfSamples, 1);
        putValueToDataSet(dataset, Tag.SampleRate, format.getSampleRate());
        putValueToDataSet(dataset, Tag.TotalTime,sound.getFrameLength()/format.getFrameRate()*1000000);        

        putValueToDataSet(dataset,Tag.SOPClassUID, UID.GeneralAudioWaveformStorage);

        byte[] bytes = convert2Byte(sound);
        if (bytes != null){
            dataset.setBytes(Tag.AudioSampleData, VR.OW,bytes);
        }

        dataset.trimToSize();

        InstanceUIDService instanceUIDService = new InstanceUIDSrvPixelmedImpl();

        String studyUID = dataset.getString(Tag.StudyInstanceUID);
        if (studyUID == null){
            studyUID = instanceUIDService.generateStudyInstanceUID();
            putValueToDataSet(dataset,Tag.StudyInstanceUID,studyUID);
        }

        String seriesUID = dataset.getString(Tag.SeriesInstanceUID);
        if (seriesUID == null){
            seriesUID = instanceUIDService.generateSeriesInstanceUID(studyUID,"1");
            putValueToDataSet(dataset,Tag.SeriesInstanceUID,seriesUID);
        }

        String sopUID = dataset.getString(Tag.SOPInstanceUID);
        if (sopUID == null){
            sopUID = instanceUIDService.generateSOPInstanceUID(studyUID,"1","1");
            putValueToDataSet(dataset,Tag.SOPInstanceUID,sopUID);
        }

        Attributes fmi = Attributes.createFileMetaInformation(
                sopUID, UID.GeneralAudioWaveformStorage , UID.ExplicitVRLittleEndian);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        DicomOutputStream dos = new DicomOutputStream(byteArrayOutputStream,UID.ExplicitVRLittleEndian);
        DicomEncodingOptions encOpts = DicomEncodingOptions.DEFAULT;
        dos.setEncodingOptions(encOpts);

        dos.writeDataset(fmi, dataset);

        dos.finish();
        dos.close();
        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
        return new DicomInputStream(byteArrayInputStream);
    }
}
